package com.bencordingley.remotecontrol;

import java.io.IOException;
import java.util.Calendar;
import java.util.TimeZone;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class Controls extends Activity implements OnSeekBarChangeListener, OnClickListener, OnLongClickListener, Callback {

	private NetworkClient client;
	private Handler handler;
	private Thread updater;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.controls);

		handler = new Handler(this);

		SeekBar sysVolume = (SeekBar) findViewById(R.id.SeekBar_Sys_Volume);
		sysVolume.setOnSeekBarChangeListener(this);
		SeekBar vlcVolume = (SeekBar) findViewById(R.id.SeekBar_VLC_Volume);
		vlcVolume.setOnSeekBarChangeListener(this);
		SeekBar position = (SeekBar) findViewById(R.id.SeekBar_Position);
		position.setOnSeekBarChangeListener(this);
		ImageButton prev = (ImageButton) findViewById(R.id.Button_Previous);
		prev.setOnClickListener(this);
		ImageButton stop = (ImageButton) findViewById(R.id.Button_Stop);
		stop.setOnClickListener(this);
		ImageButton pause = (ImageButton) findViewById(R.id.Button_Pause);
		pause.setOnClickListener(this);
		ImageButton play = (ImageButton) findViewById(R.id.Button_Play);
		play.setOnClickListener(this);
		ImageButton next = (ImageButton) findViewById(R.id.Button_Next);
		next.setOnClickListener(this);
		Button fullscreen = (Button) findViewById(R.id.Button_Fullscreen);
		fullscreen.setOnClickListener(this);
		ImageButton skipForward = (ImageButton) findViewById(R.id.Button_FF);
		skipForward.setOnClickListener(this);
		skipForward.setOnLongClickListener(this);
		ImageButton skipBackward = (ImageButton) findViewById(R.id.Button_RW);
		skipBackward.setOnClickListener(this);
		skipBackward.setOnLongClickListener(this);

		client = NetworkClient.connect(this);
	}

	private void updateSysVolumeFromNetwork() {
		try {
			SeekBar sysVolume = (SeekBar) findViewById(R.id.SeekBar_Sys_Volume);
			sysVolume.setProgress(client.getSystemVolume());
		} catch (IOException e) {
			// toast error
			e.printStackTrace();
		}
	}

	private void updatePositionFromNetwork() {
		stopUpdating();
		try {
			long duration = client.getDuration();
			long position = client.getPosition();
			SeekBar seekBar = (SeekBar) findViewById(R.id.SeekBar_Position);
			seekBar.setMax((int) duration);
			seekBar.setProgress((int) position);
			TextView dur = (TextView) findViewById(R.id.Text_Duration);
			dur.setText(timestampToString(duration));

			if (client.isRunning()) {
				startUpdating();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void updateFullscreenFromNetwork() {
		try {
			ToggleButton fullscreenButton = (ToggleButton) findViewById(R.id.Button_Fullscreen);
			fullscreenButton.setChecked(client.isFullscreen());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void updateVLCVolumeFromNetwork() {
		try {
			int volume = client.getPlayerVolume();
			SeekBar volumeBar = (SeekBar) findViewById(R.id.SeekBar_VLC_Volume);
			volumeBar.setProgress(volume);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void updateSystemVolumeFromNetwork() {
		try {
			int volume = client.getSystemVolume();
			SeekBar volumeBar = (SeekBar) findViewById(R.id.SeekBar_Sys_Volume);
			volumeBar.setProgress(volume);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (client != null) {
			updateSysVolumeFromNetwork();
			updatePositionFromNetwork();
			updateFullscreenFromNetwork();
			updateVLCVolumeFromNetwork();
			updateSystemVolumeFromNetwork();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		stopUpdating();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (client != null) {
			try {
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		stopUpdating();
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
		int id = seekBar.getId();
		if (id == R.id.SeekBar_Sys_Volume) {
			if (fromUser) {
				try {
					client.setSystemVolume((byte) progress);
				} catch (IOException e) {
					// toast error
					e.printStackTrace();
				}
			}
			((TextView) findViewById(R.id.Text_Sys_Volume)).setText(Integer.toString(progress));
		} else if (id == R.id.SeekBar_Position) {
			if (fromUser) {
				try {
					client.setPosition(progress);
				} catch (IOException e) {
					// toast error
					e.printStackTrace();
				}
			}
			TextView pos = (TextView) findViewById(R.id.Text_Position);
			pos.setText(timestampToString(progress));
		} else if (id == R.id.SeekBar_VLC_Volume) {
			if (fromUser) {
				try {
					client.setPlayerVolume((byte) progress);
				} catch (IOException e) {
					// toast error
					e.printStackTrace();
				}
			}
			((TextView) findViewById(R.id.Text_VLC_Volume)).setText(Integer.toString(progress));
		}
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		if (seekBar.getId() == R.id.SeekBar_Position) {
			stopUpdating();
		}
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		if (seekBar.getId() == R.id.SeekBar_Position) {
			try {
				if (client.isRunning()) {
					updatePositionFromNetwork();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void onClick(View arg0) {
		switch (arg0.getId()) {
		case R.id.Button_Fullscreen:
			try {
				client.setFullscreen(((ToggleButton) arg0).isChecked());
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			break;
		case R.id.Button_Next:
			try {
				client.next();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			break;
		case R.id.Button_Pause:
			pause();
			break;
		case R.id.Button_Play:
			play();
			break;
		case R.id.Button_Previous:
			try {
				client.previous();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			break;
		case R.id.Button_Stop:
			try {
				client.stopPlaying();
				stopUpdating();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			break;
		case R.id.Button_FF:
			try {
				client.skipForwardShort();
				updatePositionFromNetwork();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			break;
		case R.id.Button_RW:
			try {
				client.skipBackwardShort();
				updatePositionFromNetwork();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			break;
		}
	}

	@Override
	public boolean onLongClick(View v) {
		switch (v.getId()) {
		case R.id.Button_FF:
			try {
				client.skipForwardLong();
				updatePositionFromNetwork();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			return true;
		case R.id.Button_RW:
			try {
				client.skipBackwardLong();
				updatePositionFromNetwork();
			} catch (IOException e) {
				// toast error
				e.printStackTrace();
			}
			return true;
		}
		return false;
	}

	private void pause() {
		try {
			client.pause();
			if (client.isPaused()) {
				stopUpdating();
			} else if (client.isRunning()) {
				updatePositionFromNetwork();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void play() {
		try {
			client.play();
			if (client.isRunning()) {
				updatePositionFromNetwork();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean handleMessage(Message msg) {
		SeekBar position = (SeekBar) findViewById(R.id.SeekBar_Position);
		position.setProgress(position.getProgress() + 205);
		return true;
	}

	private void startUpdating() {
		updater = new Thread() {
			@Override
			public void run() {
				while (true) {
					handler.obtainMessage().sendToTarget();
					try {
						Thread.sleep(200);
					} catch (InterruptedException e) {
						break;
					}
				}
			}
		};
		updater.start();
	}

	private void stopUpdating() {
		if (updater != null) {
			updater.interrupt();
		}
	}

	private static String timestampToString(long timestamp) {
		String ret = "";
		Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		cal.setTimeInMillis(timestamp);
		if (cal.get(Calendar.HOUR_OF_DAY) > 0) {
			ret += cal.get(Calendar.HOUR_OF_DAY) + ":";
		}
		ret += String.format("%02d:%02d", cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
		return ret;
	}

}